package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.FormDataValidateDataHelp;
import com.xbongbong.paas.help.UserHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.pojo.dto.FormDataUpdateDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.service.ProModelService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.parent.pojo.UpdateValidateReturnPojo;
import com.xbongbong.pro.domain.entity.ReRollBackEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ProductErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.form.pojo.dto.ChildProductDTO;
import com.xbongbong.pro.formdata.pojo.vo.BeforeUpdateVO;
import com.xbongbong.pro.formdata.pojo.vo.UpdateVO;
import com.xbongbong.pro.message.pojo.dto.ConsistencySyncRabbitMqDTO;
import com.xbongbong.pro.product.pojo.ProductWithSupplierPojo;
import com.xbongbong.pro.product.pojo.ProductWithWarehousePojo;
import com.xbongbong.pro.product.pojo.StockNotifyPojo;
import com.xbongbong.pro.product.pojo.vo.ChildProductVO;
import com.xbongbong.pro.rabbitmq.producer.ConsistencySyncProducer;
import com.xbongbong.product.abstracts.AbstractProductUpdateDataService;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.domain.entity.BatchSeqOperationEntity;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.dictionary.BatchSeqOperationEnum;
import com.xbongbong.saas.help.AnalyticalHelp;
import com.xbongbong.saas.model.BatchSeqOperationModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author 吴峰
 * @date 2021/02/23 16:03
 */
@Service("productFormDataUpdateServiceImpl")
public class ProductFormDataUpdateServiceImpl extends AbstractProductUpdateDataService {

    private static final Logger LOG = LoggerFactory.getLogger(ProductFormDataUpdateServiceImpl.class);

    @Resource
    private UserHelp userHelp;
    @Resource
    private ProModelService proModelService;
    @Resource
    private ProductModel productModel;
    @Resource
    private ProductService productService;
    @Resource
    private ConsistencySyncProducer consistencySyncProducer;
    @Resource
    private ProductFormDataServiceImpl productFormDataService;
    @Resource
    private BatchSeqOperationModel batchSeqOperationModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private FormDataValidateDataHelp formDataValidateDataHelp;
    @Resource
    private AnalyticalHelp analyticalHelp;

    @Override
    public List<Integer> businessType() {
        return Arrays.asList(XbbRefTypeEnum.PRODUCT.getCode());
    }


    @Override
    public void businessImportSetData(FieldAttrEntity fieldAttrEntity, JSONObject oldData, JSONObject newData) {

    }


    @Override
    public UpdateValidateReturnPojo analyticalData(FormDataUpdateDTO formDataUpdateDTO, ValidateDataDTO validateDataDTO, PaasFormDataEntity oldPaasFormDataEntity, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        UpdateValidateReturnPojo updateValidateReturnPojo = super.analyticalData(formDataUpdateDTO, validateDataDTO, oldPaasFormDataEntity, explainMap);

        formDataUpdateDTO.setVisbleDept(validateDataDTO.getVisbleDept());
        formDataUpdateDTO.setVisbleUser(validateDataDTO.getVisbleUser());
        return updateValidateReturnPojo;
    }

    @Override
    public void importAnalyticalData(ValidateDataDTO validateDataDTO, PaasFormDataEntity oldPaasFormDataEntity, Map<String, FieldAttrEntity> explainMap, FormDataUpdateDTO formDataUpdateDTO) throws XbbException {
        super.importAnalyticalData(validateDataDTO, oldPaasFormDataEntity, explainMap, formDataUpdateDTO);

        formDataUpdateDTO.setVisbleDept(validateDataDTO.getVisbleDept());
        formDataUpdateDTO.setVisbleUser(validateDataDTO.getVisbleUser());
    }

    @Override
    public void afterSaveLog(FormDataUpdateDTO formDataUpdateDTO, PaasFormEntityExt paasFormEntityExt, PaasFormDataEntity  paasFormDataEntity, PaasFormDataEntity oldPaasFormDataEntity, UpdateVO updateVO, BeforeUpdateVO beforeUpdateVO) throws XbbException {
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.PRODUCT;
        boolean isCoverage = Objects.equals(1, formDataUpdateDTO.getIsCover());
        if(isCoverage){
           return;
        }
        // 记录日志
        JSONObject dataList = paasFormDataEntity.getData();

        String memoName = beforeUpdateVO.getPaasFormEntityExt().getName();
        String userName = updateVO.getUserVO().getName();
        StringBuilder sb = new StringBuilder();
        // 记录日志
        String productNo = dataList.getString(ProductEnum.PRODUCT_NO.getAttr());
        String opObjectName = dataList.getString(ProductEnum.NAME.getAttr());
        opObjectName = opObjectName == null ? productNo : sb.append(opObjectName).append("（").append(productNo).append("）").toString();
        // bug 26128
        dataList.put(ProductEnum.WAREHOUSE.getAttr(), dataList.getJSONArray(ProductEnum.WAREHOUSE_LINK_TEXT.getAttr()));
        JSONObject oldData = beforeUpdateVO.getOldPaasFormData().getData();
        oldData.put(ProductEnum.WAREHOUSE.getAttr(), oldData.getJSONArray(ProductEnum.WAREHOUSE_LINK_TEXT.getAttr()));
        // 26467
        paasFormDataEntity.getData().put(ProductEnum.INSTRUCTION.getAttr(), paasFormDataEntity.getData().getString(ProductEnum.INSTRUCTION.getAttr()));
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_WORK), userName, memoName, opObjectName);

        saveLogger(formDataUpdateDTO, paasFormDataEntity, redundantTemplateTypeEnum, memo, opObjectName, OperateModuleTypeEnum.PRODUCT, updateVO, beforeUpdateVO,
                OperateTypeEnum.EDIT, IndexTypeEnum.IDX_SAAS_PRODUCT_SUB);

    }

    @Override
    public UpdateVO update(FormDataUpdateDTO formDataUpdateDTO, BeforeUpdateVO beforeUpdateVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity, PaasFormDataEntity oldPaasFormDataEntity) throws XbbException {
        try {
            String corpid = formDataUpdateDTO.getCorpid();
            UserVO userVO = userHelp.getUserName(formDataUpdateDTO.getCorpid(), formDataUpdateDTO.getUserId(), formDataUpdateDTO.getLoginUserName(), paasFormDataEntity.getFlowStatus(), paasFormDataEntity.getCreatorId());
            Integer noApprovalRequired = beforeUpdateVO.getNoApprovalRequired();
            Integer updateLine = 0;
            Map<Long, String> warehouseNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, String> supplierNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<StockNotifyPojo> stockNotifyList = new ArrayList<>();
            String oldSpecificationStr = null;
            String newSpecificationStr = null;
            ChildProductVO childProductVO = null;
            Long dataId = formDataUpdateDTO.getDataId();
            if ( Objects.equals(noApprovalRequired, 1) ) {
                JSONObject oldData = oldPaasFormDataEntity.getData();

                JSONObject childData = (JSONObject) paasFormDataEntity.getData().clone();
                ProductEntityExt productEntityExt = new ProductEntityExt();
                BeanUtil.copyProperties(paasFormDataEntity, productEntityExt);
                // 获取保存需要的参数map
                JSONObject dataList = productEntityExt.getData();
                String barCode = FastJsonHelper.getStringOrDefaultFromFormData(dataList, ProductEnum.BARCODE.getAttr(), "");
                 // 如果是多规格产品保存时提示用户当前SPU下有SKU，需要开启规格字段后才能编辑保存。
                Integer oldSpec = oldData.getInteger(ProductEnum.SPECIFICATION.getAttr());
                JSONObject newSpecObj= FastJsonHelper.getJsonObjectOrDefaultFromFormData(dataList, ProductEnum.SPECIFICATION.getAttr(), new JSONObject());
                boolean specChange = Objects.equals(oldSpec, 1) && !newSpecObj.getBooleanValue(ProductConstant.ADVANCED_MODE);
                if (specChange) {
                    throw new XbbException(ProductErrorCodeEnum.API_ERROR_205042);
                }
                stockNotifyList = productService.getSaveParam(dataList, supplierNameMap, warehouseNameMap);

                productService.formatParentProduct4Save(dataList,corpid, productEntityExt);
                productFormDataService.setProductDefaultData(dataList);
                try{
                    if (Objects.equals(formDataUpdateDTO.getIsImport(), BasicConstant.ONE) && Objects.equals(formDataUpdateDTO.getIsCover(),BasicConstant.ONE)){
                        JSONArray productImgs = (JSONArray) oldData.get(ProductEnum.PRODUCT_IMGS.getAttr());
                        dataList.put(ProductEnum.PRODUCT_IMGS.getAttr(),productImgs);
                    }
                }catch (Exception e) {
                    LOG.info(e.getMessage());
                }
                if (!dataList.containsKey(ProductEnum.COST.getAttr())){
                    dataList.put(ProductEnum.COST.getAttr(),oldData.get(ProductEnum.COST.getAttr()));
                }
                FormDataUtil.removeSystemData(dataList);
                productEntityExt.setData(dataList);
                productEntityExt.setCost(dataList.getDouble(ProductEnum.COST.getAttr()));
                boolean enableMultiUnit = Objects.equals(dataList.getIntValue(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE);
                productEntityExt.setData(dataList);
                updateLine = productModel.update(productEntityExt);
                // 规格还得放回去，后面多规格有用
                productEntityExt.getData().put(ProductEnum.SPECIFICATION.getAttr(), newSpecObj);
                // 子产品需要存入条码
                productEntityExt.getData().put(ProductEnum.BARCODE.getAttr(), barCode);
                if (enableMultiUnit) {
                    productEntityExt.getData().put(ProductEnum.PRICE.getAttr(), childData.get(ProductEnum.PRICE.getAttr()));
                }
                // 子表单保存
                ((ProductEntityExt)oldPaasFormDataEntity).setNum(null);
                ((ProductEntityExt)oldPaasFormDataEntity).setCost(null);
                ((ProductEntityExt)oldPaasFormDataEntity).setTotalCost(null);

                // 被裹挟的产品封面图：有图片时第一张图片为封面图；无图片时删除封面图
                JSONArray images = dataList.getJSONArray(ProductEnum.PRODUCT_IMGS.getAttr());
                JSONArray thumbnails = new JSONArray();
                if(images != null && images.size() > 0) {
                    thumbnails.add(images.get(0));
                    childData.put(ProductEnum.THUMBNAIL.getAttr(), thumbnails);
                } else {
                    childData.put(ProductEnum.THUMBNAIL.getAttr(), thumbnails);
                    childData.put(ProductEnum.PRODUCT_IMGS.getAttr(), new JSONArray());
                }
                paasFormDataEntity.setData(childData);
                // 保存子产品
                FieldAttrEntity fieldAttrEntity = formDataUpdateDTO.getExplainMap().get(ProductEnum.COST.getAttr());
                Integer costAccuracy = Objects.isNull(fieldAttrEntity) ? null : fieldAttrEntity.getAccuracy();
                // 规格存在子产品中，拿子产品数据更新关联产品表的规格, 多规格的不可编辑规格，这里只处理单规格的

                try {
                    JSONObject specificationObj = childData.getJSONObject(ProductEnum.SPECIFICATION.getAttr());
                    Boolean advancedMode = specificationObj.getBoolean("advancedMode");
                    if (advancedMode != null && !advancedMode) {
                        newSpecificationStr = specificationObj.getString("specValue");
                        ChildProductDTO childProductDTO = new ChildProductDTO();
                        childProductDTO.setCorpid(corpid);
                        childProductDTO.setParentProductId(Collections.singletonList(dataId));
                        PaasFormDataEsListVO esDataList = productService.getChildProductList(childProductDTO);
                        List<PaasFormDataEntityExt> paasFormDataESList = esDataList.getPaasFormDataESList();
                        if (Objects.nonNull(paasFormDataESList) && paasFormDataESList.size() > 0) {
                            JSONObject childSingeData = paasFormDataESList.get(0).getData();
                            oldSpecificationStr = childSingeData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
                        }
                    }
                } catch (Exception e) {
                    LOG.error("product update get specification fail", e);
                }
                productFormDataService.setProductDefaultData(childData);
                childData.put(ProductEnum.WAREHOUSE.getAttr(),dataList.getJSONArray(ProductEnum.WAREHOUSE.getAttr()));
                childData.put(ProductEnum.WAREHOUSE_LINK_TEXT.getAttr(),dataList.getJSONArray(ProductEnum.WAREHOUSE_LINK_TEXT.getAttr()));
                childData.put(ProductEnum.SUPPLIER.getAttr(),dataList.getJSONArray(ProductEnum.SUPPLIER.getAttr()));
                childData.put(ProductEnum.SUPPLIER_LINK_TEXT.getAttr(),dataList.getJSONArray(ProductEnum.SUPPLIER_LINK_TEXT.getAttr()));
                // 保存子产品
                FormDataUtil.removeSystemData(paasFormDataEntity.getData());
                Object richTextData = removeRichText(paasFormDataEntity.getData());
                childProductVO = productService.saveChildProduct(paasFormDataEntity, true, false, costAccuracy);

                Boolean isJxcUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
                if (isJxcUse) {

                    productService.associateWithSupplier(new ProductWithSupplierPojo(corpid, childProductVO, supplierNameMap, dataId));
                    ProductWithWarehousePojo productWithWarehousePojo = new ProductWithWarehousePojo(corpid, childProductVO, warehouseNameMap, dataId, stockNotifyList, false, dataList.getDouble(ProductEnum.COST.getAttr()));
                    BeanUtil.copyProperties(formDataUpdateDTO, productWithWarehousePojo);
                    if (Objects.nonNull(formDataUpdateDTO.getSaasNeedRedundantAttrPoJo())) {
                        productWithWarehousePojo.setProductWarehouseSavePojo(formDataUpdateDTO.getSaasNeedRedundantAttrPoJo().getProductWarehouseSavePojo());
                    }
                    productService.associateWithWarehouse(productWithWarehousePojo);

                    Integer oldBatchControl = getIntegerOrDefaultFromFormData(oldData, ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), 0);
                    Integer oldSerialNumberControl = getIntegerOrDefaultFromFormData(oldData, ProductEnum.ENABLE_SERIAL_NUMBER.getAttr(), 0);
                    Integer batchControl = getIntegerOrDefaultFromFormData(dataList, ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), 0);
                    Integer serialNumberControl = getIntegerOrDefaultFromFormData(dataList, ProductEnum.ENABLE_SERIAL_NUMBER.getAttr(), 0);
                    boolean oldShelfLifeDay = StringUtil.isEmpty(oldData.getString(ProductEnum.SHELF_LIFE_DAYS.getAttr()));
                    boolean shelfLifeDay = StringUtil.isEmpty(dataList.getString(ProductEnum.SHELF_LIFE_DAYS.getAttr()));
                    //编辑产品时需要判断是否开启或者关闭批次号,是否开启或者关闭序列号，是否开启或者关闭保质期（以是否为空为准）
                    Integer batchType = null;
                    Integer seqType = null;
                    Integer enableGuaranteePeriodType = null;
                    BatchSeqOperationEntity entity = new BatchSeqOperationEntity();
                    entity.setCorpid(corpid);
                    entity.setParentId(dataId);
                    if (oldBatchControl == 0 && batchControl == 1){
                        batchType = BatchSeqOperationEnum.ENABLEBATCH.getCode();
                        ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, 1);
                        consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.BATCH_FLOW_BILL);
                    }else if (oldBatchControl == 1 && batchControl == 0){
                        batchType = BatchSeqOperationEnum.DISABLEBATCH.getCode();
                        ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, 0);
                        consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.BATCH_FLOW_BILL);
                    }
                    if (Objects.nonNull(batchType)) {
                        entity.setType(batchType);
                        batchSeqOperationModel.insert(entity);
                    }
                    // 开启/关闭保质期
                    if (oldShelfLifeDay && !shelfLifeDay){
                        enableGuaranteePeriodType = BatchSeqOperationEnum.ENABLEGUARANTEEPERIOD.getCode();
                    }else if (!oldShelfLifeDay && shelfLifeDay){
                        enableGuaranteePeriodType = BatchSeqOperationEnum.DISABLEGUARANTEEPERIOD.getCode();
                    }
                    if (Objects.nonNull(enableGuaranteePeriodType)) {
                        entity.setType(enableGuaranteePeriodType);
                        batchSeqOperationModel.insert(entity);
                    }
                    // 序列号的开启/关闭
                    if (oldSerialNumberControl == 0 && serialNumberControl == 1){
                        seqType = BatchSeqOperationEnum.ENABLESEQ.getCode();
                        ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, 1);
                        consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.SEQ_SEARCH);
                    }else if (oldSerialNumberControl == 1 && serialNumberControl == 0){
                        seqType = BatchSeqOperationEnum.DISABLESEQ.getCode();
                        ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, 0);
                        consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.SEQ_SEARCH);
                    }
                    if (Objects.nonNull(seqType)) {
                        entity.setType(seqType);
                        batchSeqOperationModel.insert(entity);
                    }
                }
                // 设置属性用于返回
                setPartialAttributes(productEntityExt.getSubFormData(), productEntityExt.getData(),
                        productEntityExt.getUpdateTime(), productEntityExt.getAddTime(), productEntityExt.getSerialNo(),
                        productEntityExt.getDepartmentId(), productEntityExt.getOwnerId(),
                        paasFormDataEntity, beforeUpdateVO);
                //文件柜数据保存
                saveFile(formDataUpdateDTO, paasFormDataEntity, userVO);
                //富文本数据更新
                updateFormRichText(formDataUpdateDTO, richTextData);
            }
            return new UpdateVO(noApprovalRequired, paasFormDataEntity, paasFormDataEntity.getDataId(), updateLine, userVO, childProductVO, oldSpecificationStr, newSpecificationStr );
        } catch (XbbException e) {
            afterSaveRollBack(formDataUpdateDTO, null, beforeUpdateVO, new ReRollBackEntity());
            throw e;
        } catch (Exception e) {
            afterSaveRollBack(formDataUpdateDTO, null, beforeUpdateVO, new ReRollBackEntity());
            LOG.error("purchaseInvoiceFormDataUpdateServiceImpl.update 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }


    @Override
    public FormDataUpdateVO afterSave(FormDataUpdateDTO formDataUpdateDTO, BeforeUpdateVO beforeUpdateVO, UpdateVO updateVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity, PaasFormDataEntity oldPaasFormDataEntity) throws XbbException {
        String corpid = formDataUpdateDTO.getCorpid();
        Long dataId = formDataUpdateDTO.getDataId();
        Integer businessType = formDataUpdateDTO.getBusinessType();
        try {
            FormDataUpdateVO formDataUpdateVO = new FormDataUpdateVO();
            Integer noApprovalRequired = updateVO.getNoApprovalRequired();
            if (Objects.equals(1, noApprovalRequired)) {
                SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
                JSONObject dataList = paasFormDataEntity.getData();
                JSONObject oldData = oldPaasFormDataEntity.getData();
                BeanUtil.copyProperties(formDataUpdateDTO, saasFormSaveDTO);
                packageSaasFormUpdateSaveDTO(saasFormSaveDTO, paasFormDataEntity, oldPaasFormDataEntity);
                ChildProductVO childProductVO = updateVO.getChildProductVO();
                saasFormSaveDTO.setChildProductVO(childProductVO);
                productService.afterSave(saasFormSaveDTO);
                String oldSpecificationStr = updateVO.getOldSpecificationStr();
                String newSpecificationStr = updateVO.getNewSpecificationStr();
                //父产品的名称和编号更新
                String oldProductName = oldData.getString(ProductEnum.NAME.getAttr());
                String oldProductNo = oldData.getString(ProductEnum.PRODUCT_NO.getAttr());
                String opObjectName = dataList.getString(ProductEnum.NAME.getAttr());
                String newProductNo = dataList.getString(ProductEnum.PRODUCT_NO.getAttr());
                if (!Objects.equals(oldProductName, opObjectName) || !Objects.equals(oldProductNo, newProductNo) || !Objects.equals(oldSpecificationStr, newSpecificationStr)) {
                    ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(formDataUpdateDTO.getCorpid(), paasFormDataEntity.getId(), opObjectName, null, newSpecificationStr, newProductNo);
                    consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.PRODUCT);
                }
                // 日志
                afterSaveLog(formDataUpdateDTO, paasFormEntity, paasFormDataEntity, oldPaasFormDataEntity, updateVO, beforeUpdateVO);
                // api发起
                apiHook(formDataUpdateDTO, updateVO, beforeUpdateVO);

                // 2021/3/3 业务规则
                activeRule(formDataUpdateDTO, beforeUpdateVO, updateVO);
                formDataUpdateVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
                formDataUpdateVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
            } else if (Objects.equals(noApprovalRequired, 2)) {
                // 自动拒绝
                formDataUpdateVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                formDataUpdateVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
            } else {
                formDataUpdateVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                formDataUpdateVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
                PaasProcessDataEntity paasProcessDataEntity = new PaasProcessDataEntity();
                paasProcessDataEntity.setCorpid(formDataUpdateDTO.getCorpid());
                paasProcessDataEntity.setFormDataId(dataId);
                paasProcessDataEntity.setBusinessType(businessType);
                paasProcessDataEntity.setSaasMark(formDataUpdateDTO.getSaasMark());
                proModelService.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.IN_APPROVAL.getType());
            }
            formDataUpdateVO.setFormDataId(dataId);
            return formDataUpdateVO;
        } catch (XbbException e) {
            afterSaveRollBack(formDataUpdateDTO, updateVO, beforeUpdateVO, new ReRollBackEntity());
            throw e;
        } catch (Exception e) {
            afterSaveRollBack(formDataUpdateDTO, updateVO, beforeUpdateVO, new ReRollBackEntity());
            LOG.error("purchaseInvoiceFormDataUpdateServiceImpl.afterSave 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public void apiHook(FormDataUpdateDTO formDataUpdateDTO, UpdateVO updateVO, BeforeUpdateVO beforeUpdateVO) throws XbbException {
        // 第三方服务
        lowCodeExecuteService(formDataUpdateDTO, updateVO, beforeUpdateVO);
    }

    @Override
    public UpdateVO updateForWorkflow(FormDataUpdateDTO formDataUpdateDTO, BeforeUpdateVO beforeUpdateVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity, PaasFormDataEntity oldPaasFormDataEntity) throws XbbException {
        try {
            String corpid = formDataUpdateDTO.getCorpid();
            UserVO userVO = userHelp.getUserName(formDataUpdateDTO.getCorpid(), formDataUpdateDTO.getUserId(), formDataUpdateDTO.getLoginUserName(), beforeUpdateVO.getPaasFormDataEntity().getFlowStatus(), beforeUpdateVO.getPaasFormDataEntity().getCreatorId());
            Integer noApprovalRequired = beforeUpdateVO.getNoApprovalRequired();
            Long dataId = formDataUpdateDTO.getDataId();
            Integer updateLine = 0;
            Map<Long, String> warehouseNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, String> supplierNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<StockNotifyPojo> stockNotifyList = new ArrayList<>();
            JSONObject oldData = oldPaasFormDataEntity.getData();

            JSONObject childData = (JSONObject) paasFormDataEntity.getData().clone();
            ProductEntityExt productEntityExt = new ProductEntityExt();
            BeanUtil.copyProperties(paasFormDataEntity, productEntityExt);
            // 获取保存需要的参数map
            JSONObject dataList = productEntityExt.getData();
            String barCode = FastJsonHelper.getStringOrDefaultFromFormData(dataList, ProductEnum.BARCODE.getAttr(), "");
            // 如果是多规格产品保存时提示用户当前SPU下有SKU，需要开启规格字段后才能编辑保存。
            Integer oldSpec = oldData.getInteger(ProductEnum.SPECIFICATION.getAttr());
            JSONObject newSpecObj= FastJsonHelper.getJsonObjectOrDefaultFromFormData(dataList, ProductEnum.SPECIFICATION.getAttr(), new JSONObject());
            boolean specChange = Objects.equals(oldSpec, 1) && !newSpecObj.getBooleanValue(ProductConstant.ADVANCED_MODE);
            if (specChange) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205042);
            }
            stockNotifyList = productService.getSaveParam(dataList, supplierNameMap, warehouseNameMap);

            productService.formatParentProduct4Save(dataList,corpid, productEntityExt);
            productFormDataService.setProductDefaultData(dataList);
            try{
                if (Objects.equals(formDataUpdateDTO.getIsImport(), BasicConstant.ONE) && Objects.equals(formDataUpdateDTO.getIsCover(),BasicConstant.ONE)){
                    JSONArray productImgs = (JSONArray) oldData.get(ProductEnum.PRODUCT_IMGS.getAttr());
                    dataList.put(ProductEnum.PRODUCT_IMGS.getAttr(),productImgs);
                }
            }catch (Exception e) {
                LOG.info(e.getMessage());
            }
            if (!dataList.containsKey(ProductEnum.COST.getAttr())){
                dataList.put(ProductEnum.COST.getAttr(),oldData.get(ProductEnum.COST.getAttr()));
            }
            FormDataUtil.removeSystemData(dataList);
            Object richTextData = removeRichText(dataList);
            productEntityExt.setData(dataList);
            productEntityExt.setCost(dataList.getDouble(ProductEnum.COST.getAttr()));
            boolean enableMultiUnit = Objects.equals(dataList.getIntValue(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE);
            productEntityExt.setData(dataList);
            if (enableMultiUnit) {
                childData.put(ProductEnum.PRICE.getAttr(), productEntityExt.getData().get(ProductEnum.PRICE.getAttr()));
                productEntityExt.getData().remove(ProductEnum.PRICE.getAttr());
            }
            updateLine = productModel.update(productEntityExt);
            // 规格还得放回去，后面多规格有用
            productEntityExt.getData().put(ProductEnum.SPECIFICATION.getAttr(), newSpecObj);
            // 子产品需要存入条码
            productEntityExt.getData().put(ProductEnum.BARCODE.getAttr(), barCode);
            if (enableMultiUnit) {
                productEntityExt.getData().put(ProductEnum.PRICE.getAttr(), childData.get(ProductEnum.PRICE.getAttr()));
            }
            ((ProductEntityExt)oldPaasFormDataEntity).setNum(null);
            ((ProductEntityExt)oldPaasFormDataEntity).setCost(null);
            ((ProductEntityExt)oldPaasFormDataEntity).setTotalCost(null);

            // 被裹挟的产品封面图：有图片时第一张图片为封面图；无图片时删除封面图
            JSONArray images = dataList.getJSONArray(ProductEnum.PRODUCT_IMGS.getAttr());
            JSONArray thumbnails = new JSONArray();
            if(images != null && images.size() > 0) {
                thumbnails.add(images.get(0));
                childData.put(ProductEnum.THUMBNAIL.getAttr(), thumbnails);
            } else {
                childData.put(ProductEnum.THUMBNAIL.getAttr(), thumbnails);
                childData.put(ProductEnum.PRODUCT_IMGS.getAttr(), new JSONArray());
            }
            paasFormDataEntity.setData(childData);
            // 保存子产品
            FieldAttrEntity fieldAttrEntity = formDataUpdateDTO.getExplainMap().get(ProductEnum.COST.getAttr());
            Integer costAccuracy = Objects.isNull(fieldAttrEntity) ? null : fieldAttrEntity.getAccuracy();
            // 规格存在子产品中，拿子产品数据更新关联产品表的规格, 多规格的不可编辑规格，这里只处理单规格的

            String newSpecificationStr = null;
            String oldSpecificationStr = null;
            try {
                JSONObject specificationObj = childData.getJSONObject(ProductEnum.SPECIFICATION.getAttr());
                Boolean advancedMode = specificationObj.getBoolean("advancedMode");
                if (advancedMode != null && !advancedMode) {
                    newSpecificationStr = specificationObj.getString("specValue");
                    ChildProductDTO childProductDTO = new ChildProductDTO();
                    childProductDTO.setCorpid(corpid);
                    childProductDTO.setParentProductId(Collections.singletonList(dataId));
                    PaasFormDataEsListVO esDataList = productService.getChildProductList(childProductDTO);
                    List<PaasFormDataEntityExt> paasFormDataESList = esDataList.getPaasFormDataESList();
                    if (Objects.nonNull(paasFormDataESList) && paasFormDataESList.size() > 0) {
                        JSONObject childSingeData = paasFormDataESList.get(0).getData();
                        oldSpecificationStr = childSingeData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
                    }
                }
            } catch (Exception e) {
                LOG.error("product update get specification fail", e);
            }
            productFormDataService.setProductDefaultData(childData);
            childData.put(ProductEnum.WAREHOUSE.getAttr(),dataList.getJSONArray(ProductEnum.WAREHOUSE.getAttr()));
            childData.put(ProductEnum.WAREHOUSE_LINK_TEXT.getAttr(),dataList.getJSONArray(ProductEnum.WAREHOUSE_LINK_TEXT.getAttr()));
            childData.put(ProductEnum.SUPPLIER.getAttr(),dataList.getJSONArray(ProductEnum.SUPPLIER.getAttr()));
            childData.put(ProductEnum.SUPPLIER_LINK_TEXT.getAttr(),dataList.getJSONArray(ProductEnum.SUPPLIER_LINK_TEXT.getAttr()));
            // 保存子产品
            FormDataUtil.removeSystemData(paasFormDataEntity.getData());
            ChildProductVO childProductVO = productService.saveChildProduct(paasFormDataEntity, true, false, costAccuracy);

            Boolean isJxcUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
            if (isJxcUse) {

                productService.associateWithSupplier(new ProductWithSupplierPojo(corpid, childProductVO, supplierNameMap, dataId));
                ProductWithWarehousePojo productWithWarehousePojo = new ProductWithWarehousePojo(corpid, childProductVO, warehouseNameMap, dataId, stockNotifyList, false, dataList.getDouble(ProductEnum.COST.getAttr()));
                BeanUtil.copyProperties(formDataUpdateDTO, productWithWarehousePojo);
                if (Objects.nonNull(formDataUpdateDTO.getSaasNeedRedundantAttrPoJo())) {
                    productWithWarehousePojo.setProductWarehouseSavePojo(formDataUpdateDTO.getSaasNeedRedundantAttrPoJo().getProductWarehouseSavePojo());
                }
                productService.associateWithWarehouse(productWithWarehousePojo);

                Integer oldBatchControl = getIntegerOrDefaultFromFormData(oldData, ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), 0);
                Integer oldSerialNumberControl = getIntegerOrDefaultFromFormData(oldData, ProductEnum.ENABLE_SERIAL_NUMBER.getAttr(), 0);
                Integer batchControl = getIntegerOrDefaultFromFormData(dataList, ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), 0);
                Integer serialNumberControl = getIntegerOrDefaultFromFormData(dataList, ProductEnum.ENABLE_SERIAL_NUMBER.getAttr(), 0);
                boolean oldShelfLifeDay = StringUtil.isEmpty(oldData.getString(ProductEnum.SHELF_LIFE_DAYS.getAttr()));
                boolean shelfLifeDay = StringUtil.isEmpty(dataList.getString(ProductEnum.SHELF_LIFE_DAYS.getAttr()));
                //编辑产品时需要判断是否开启或者关闭批次号,是否开启或者关闭序列号，是否开启或者关闭保质期（以是否为空为准）
                Integer batchType = null;
                Integer seqType = null;
                Integer enableGuaranteePeriodType = null;
                BatchSeqOperationEntity entity = new BatchSeqOperationEntity();
                entity.setCorpid(corpid);
                entity.setParentId(dataId);
                if (oldBatchControl == 0 && batchControl == 1){
                    batchType = BatchSeqOperationEnum.ENABLEBATCH.getCode();
                    ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, 1);
                    consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.BATCH_FLOW_BILL);
                }else if (oldBatchControl == 1 && batchControl == 0){
                    batchType = BatchSeqOperationEnum.DISABLEBATCH.getCode();
                    ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, 0);
                    consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.BATCH_FLOW_BILL);
                }
                if (Objects.nonNull(batchType)) {
                    entity.setType(batchType);
                    batchSeqOperationModel.insert(entity);
                }
                // 开启/关闭保质期
                if (oldShelfLifeDay && !shelfLifeDay){
                    enableGuaranteePeriodType = BatchSeqOperationEnum.ENABLEGUARANTEEPERIOD.getCode();
                }else if (!oldShelfLifeDay && shelfLifeDay){
                    enableGuaranteePeriodType = BatchSeqOperationEnum.DISABLEGUARANTEEPERIOD.getCode();
                }
                if (Objects.nonNull(enableGuaranteePeriodType)) {
                    entity.setType(enableGuaranteePeriodType);
                    batchSeqOperationModel.insert(entity);
                }
                // 序列号的开启/关闭
                if (oldSerialNumberControl == 0 && serialNumberControl == 1){
                    seqType = BatchSeqOperationEnum.ENABLESEQ.getCode();
                    ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, 1);
                    consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.SEQ_SEARCH);
                }else if (oldSerialNumberControl == 1 && serialNumberControl == 0){
                    seqType = BatchSeqOperationEnum.DISABLESEQ.getCode();
                    ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, 0);
                    consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.SEQ_SEARCH);
                }
                if (Objects.nonNull(seqType)) {
                    entity.setType(seqType);
                    batchSeqOperationModel.insert(entity);
                }
            }
            // 设置属性用于返回
            setPartialAttributes(productEntityExt.getSubFormData(), productEntityExt.getData(),
                    productEntityExt.getUpdateTime(), productEntityExt.getAddTime(), productEntityExt.getSerialNo(),
                    productEntityExt.getDepartmentId(), productEntityExt.getOwnerId(),
                    paasFormDataEntity, beforeUpdateVO);
            //文件柜数据保存
//            saveFile(formDataUpdateDTO, paasFormDataEntity, userVO);
            //富文本数据保存
            Integer updateRichTextLine = updateFormRichText(formDataUpdateDTO, richTextData);
            //表单数据和富文本数据其中有一个编辑就要进工作流
            updateLine = Objects.equals(updateLine, 1) || Objects.equals(updateRichTextLine, 1) ? 1 : 0;

            return new UpdateVO(noApprovalRequired, paasFormDataEntity, paasFormDataEntity.getDataId(), updateLine, userVO, childProductVO, oldSpecificationStr, newSpecificationStr);
        } catch (XbbException e) {
            afterSaveRollBack(formDataUpdateDTO, null, beforeUpdateVO, new ReRollBackEntity());
            throw e;
        } catch (Exception e) {
            afterSaveRollBack(formDataUpdateDTO, null, beforeUpdateVO, new ReRollBackEntity());
            LOG.error("purchaseInvoiceFormDataUpdateServiceImpl.update 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public FormDataUpdateVO afterSaveForWorkflow(FormDataUpdateDTO formDataUpdateDTO, BeforeUpdateVO beforeUpdateVO, UpdateVO updateVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity, PaasFormDataEntity oldPaasFormDataEntity) throws XbbException {
        String corpid = formDataUpdateDTO.getCorpid();
        Long dataId = formDataUpdateDTO.getDataId();
        Integer businessType = formDataUpdateDTO.getBusinessType();
        try {
            FormDataUpdateVO formDataUpdateVO = new FormDataUpdateVO();
            Integer noApprovalRequired = updateVO.getNoApprovalRequired();
            SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();

            BeanUtil.copyProperties(formDataUpdateDTO, saasFormSaveDTO);
            JSONObject oldData = oldPaasFormDataEntity.getData();
            JSONObject dataList = paasFormDataEntity.getData();
            String oldSpecificationStr = updateVO.getOldSpecificationStr();
            String newSpecificationStr = updateVO.getNewSpecificationStr();

            productService.afterSaveForUpdateWorkflow(saasFormSaveDTO);
            //父产品的名称和编号更新
//            String oldProductName = oldData.getString(ProductEnum.NAME.getAttr());
//            String oldProductNo = oldData.getString(ProductEnum.PRODUCT_NO.getAttr());
//            String opObjectName = dataList.getString(ProductEnum.NAME.getAttr());
//            String newProductNo = dataList.getString(ProductEnum.PRODUCT_NO.getAttr());
//            if (!Objects.equals(oldProductName, opObjectName) || !Objects.equals(oldProductNo, newProductNo) || !Objects.equals(oldSpecificationStr, newSpecificationStr)) {
//                ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(productEntityExt.getCorpid(), productEntityExt.getId(), opObjectName, null, newSpecificationStr, newProductNo);
//                consistencySyncProducer.syncData(consistencySyncRabbitMqDTO, XbbRefTypeEnum.PRODUCT);
//            }
            // 日志
//            afterSaveLog(formDataUpdateDTO, paasFormDataEntity, updateVO, beforeUpdateVO);
            // api发起
//            apiHook(formDataUpdateDTO, updateVO, beforeUpdateVO);
            // 2021/3/3 业务规则
//            activeRule(formDataUpdateDTO, beforeUpdateVO, updateVO);

            formDataUpdateVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
            formDataUpdateVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
//            PaasProcessDataEntity paasProcessDataEntity = new PaasProcessDataEntity();
//            paasProcessDataEntity.setCorpid(formDataUpdateDTO.getCorpid());
//            paasProcessDataEntity.setFormDataId(dataId);
//            paasProcessDataEntity.setBusinessType(businessType);
//            paasProcessDataEntity.setSaasMark(formDataUpdateDTO.getSaasMark());
//            proModelService.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.IN_APPROVAL.getType());
            formDataUpdateVO.setFormDataId(dataId);
            return formDataUpdateVO;
        } catch (XbbException e) {
            afterSaveRollBack(formDataUpdateDTO, updateVO, beforeUpdateVO, new ReRollBackEntity());
            throw e;
        } catch (Exception e) {
            afterSaveRollBack(formDataUpdateDTO, updateVO, beforeUpdateVO, new ReRollBackEntity());
            LOG.error("purchaseInvoiceFormDataUpdateServiceImpl.afterSave 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public Long backupData(FormDataUpdateDTO formDataUpdateDTO, BeforeUpdateVO beforeUpdateVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity, PaasFormDataEntity oldPaasFormDataEntity) {
        // 没有审批无需备份
        return null;
    }

    @Override
    public JSONObject backupDataOtherInfo(JSONObject data, String corpid, Long dataId) {
        return data;
    }
}
